//
//  ParticleEmitter.m
//  Void Dead
//
//  Created by Sidney Just on 12.09.09.
//  Copyright 2009 Sidney Just
//  This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; 
//  either version 3 of the License, or (at your option) any later version.
//  
//  This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty 
//  of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
//  

#import "ParticleEmitter.h"
#import "panelManager.h"
#import "panel.h"
#import "Particle.h"
#import "Engine.h"

@implementation VD_ParticleEmitter
@synthesize pos_x, pos_y, gain_X, gain_Y, lifespan, maxParticles, layer, randomX, randomY, gravityX, gravityY, globalLifespan, gainSize_x, gainSize_y, spawnPerFrame, bright;

- (id)initWithEngine:(VD_Engine *)engine {
	if(self = [super init])
	{
		ccEngine = engine;
		panMan = ccEngine->panManager;
		
		texture = -1;
		
		maxParticles = 0;
		currParticles = 0;
		particles = (VD_Particle **)malloc(sizeof(VD_Particle *));
		
		gain_X = 0;
		gain_Y = 0;
		
		randomX = 0;
		randomY = 0;
		
		gainSize_x = 0;
		gainSize_y = 0;
		
		layer = 0;
		
		gravityX = 0;
		gravityY = 0;
		
		globalLifespan = 0;
		glifespan = 0;
		
		spawnPerFrame = 1;
		
		bright = NO;
		
		lifespan = 1;
	}
	return self;
}

- (id)init {
	NSException* thisException = [NSException exceptionWithName:@"EmitterInvalid" reason:@"Invalid init for Emitter. Use initWithEngine:" userInfo:nil];
	@throw thisException;
}

- (void)dealloc {
	for(int i=0; i<currParticles; i++)
	{
		[panMan deletePanel:particles[i].panel];
		[particles[i] release];
	}
	
	free(particles);
	
	[super dealloc];
}

- (void)setTexture:(int)tex {
	texture = tex;
	
	texWidth = ccEngine->texManager.size[texture].x;
	texHeight = ccEngine->texManager.size[texture].y;
}

- (void)removeParticle:(VD_Particle *)p {
	for(int i=0; i<currParticles; i++)
	{
		if(p == particles[i])
		{
			[panMan deletePanel:particles[i].panel];
			[particles[i] release];
			
			for(int j=i; j<currParticles-1; j++)
			{
				particles[j] = particles[j+1];
			}
			
			currParticles -= 1;
			particles = (VD_Particle **)realloc(particles, currParticles*sizeof(VD_Particle *));
			
			break;
		}
	}
}

- (void)updateParticles {
	BOOL loop = YES;
	
	for(int i=0; i<currParticles; i++)
	{
		[particles[i] updateMe];
	}
	
	while(loop == YES)
	{
		loop = NO;
		
		for(int i=0; i<currParticles; i++)
		{
			if(particles[i].lifespan <= 0)
			{
				[self removeParticle:particles[i]];
				
				loop = YES;
				break;
			}
		}
	}
}

- (void)spawnParticles {
	if(globalLifespan > 0)
		glifespan += ccEngine->timeStep;
	
	if(glifespan >= globalLifespan && globalLifespan > 0)
	{
		maxParticles = 0;
		
		if(currParticles == 0)
		{
			[ccEngine->panManager deleteParticleEmitter:self];
			return;
		}
	}
	
	for(int i=0; i<spawnPerFrame; i++)
	{
		if(currParticles < maxParticles && texture > -1)
		{
			int i = currParticles;
			currParticles += 1;
			particles = (VD_Particle **)realloc(particles, currParticles*sizeof(VD_Particle *));
			
			particles[i] = [[VD_Particle alloc] initWithEngine:ccEngine andLayer:layer andTexture:texture];
			
			particles[i].pos_x = pos_x-(texWidth/2);
			particles[i].pos_y = pos_y-(texHeight/2);
			
			particles[i].gain_X = gain_X;
			particles[i].gain_Y = gain_Y;
			
			particles[i].gainSize_x = gainSize_x;
			particles[i].gainSize_y = gainSize_y;
			
			particles[i].randomX = randomX;
			particles[i].randomY = randomY;
			
			particles[i].gravityX = gravityX;
			particles[i].gravityY = gravityY;
			
			particles[i].panel.rotation = arc4random()%360;
			particles[i].panel.userData = self;
			
			particles[i].lifespan = lifespan;
			
			[particles[i] setDirection];
		}
	}
	
	[self updateParticles];
}

@end
